package com.game.objects;

import java.util.ArrayList;
import java.util.ListIterator;
import java.util.concurrent.Callable;

import javax.swing.ImageIcon;

import com.game.level.LevelLoader;
import com.game.level.Terrain;
import com.jme.image.Texture;
import com.jme.math.Vector3f;
import com.jme.renderer.Renderer;
import com.jme.scene.Node;
import com.jme.scene.SceneElement;
import com.jme.scene.Skybox;
import com.jme.scene.Spatial;
import com.jme.scene.state.CullState;
import com.jme.scene.state.FogState;
import com.jme.scene.state.LightState;
import com.jme.scene.state.TextureState;
import com.jme.scene.state.ZBufferState;
import com.jme.system.DisplaySystem;
import com.jme.util.GameTaskQueueManager;
import com.jme.util.TextureManager;

public class Environment implements Callable<Object>{
	private Node ev;
	public DisplaySystem display;
	private LevelLoader lvlLoader;
	public CullState cs;
	public Texture t1;
	public Texture texDetail;
	public ImageIcon grass;
	public ImageIcon dirt;
	public ImageIcon highest;
	private Skybox skybox;
	public final float baseSpeed = 60f;
	private float currentSpeed;
	private ArrayList<Enemy> enemys = new ArrayList<Enemy>();
	private Player player;
	
	public Environment(){
		display = DisplaySystem.getDisplaySystem();
		ev = new Node("Environment");
		loadTextures();
		buildSkyBox();
		currentSpeed = baseSpeed;
		lvlLoader = new LevelLoader(this,"testlevel1.xml",2);
		GameTaskQueueManager.getManager().update(this);
	}
	public Node getEnvironment() {
		return ev;
	}
	public void setSpeed(float currentSpeed){
		this.currentSpeed = currentSpeed;
	}
	
	public boolean checkSimpleCollision(Spatial obj){
		ListIterator child = ev.getChildren().listIterator();
		while(child.hasNext()){
			Spatial test = (Spatial) child.next();
			if(test instanceof Terrain){
				Terrain t = (Terrain)test;
				if(t.checkSimpleCollision(obj)){
					return true;			
				}
			}
		}
		ListIterator<Enemy> es = enemys.listIterator();
		while(es.hasNext()){
			Enemy e = es.next();
			if(e.checkSimpleCollision(obj)){
				return true;
			}
		}
		return false;
	}
	
	
	
	private void loadTextures(){
	    cs = display.getRenderer().createCullState();
	    cs.setCullMode(CullState.CS_BACK);
	    cs.setEnabled(true);
	    
        grass = new ImageIcon(Environment.class.getClassLoader()
                .getResource("jmetest/data/texture/grassb.png"));
        dirt= new ImageIcon(Environment.class.getClassLoader()
                .getResource("jmetest/data/texture/dirt.jpg"));
        highest =new ImageIcon(Environment.class.getClassLoader()
                .getResource("jmetest/data/texture/highest.jpg"));
        	
        texDetail = TextureManager.loadTexture(
        		Environment.class.getClassLoader().getResource(
            "jmetest/data/texture/Detail.jpg"),
            Texture.MM_LINEAR_LINEAR,
            Texture.FM_LINEAR);

        texDetail.setWrap(Texture.WM_WRAP_S_WRAP_T);

        texDetail.setApply(Texture.AM_COMBINE);
        texDetail.setCombineFuncRGB(Texture.ACF_ADD_SIGNED);
        texDetail.setCombineSrc0RGB(Texture.ACS_TEXTURE);
        texDetail.setCombineOp0RGB(Texture.ACO_SRC_COLOR);
        texDetail.setCombineSrc1RGB(Texture.ACS_PREVIOUS);
        texDetail.setCombineOp1RGB(Texture.ACO_SRC_COLOR);
        texDetail.setCombineScaleRGB(1.0f);
        
		ev.setRenderQueueMode(Renderer.QUEUE_OPAQUE);
	}
	
	private void buildSkyBox() {
		skybox = new Skybox( "skybox", 10, 10, 10 );

		String dir = "jmetest/effects/water/data/";
		Texture north = TextureManager.loadTexture(
				Environment.class.getClassLoader().getResource(
						dir + "1.jpg" ),
				Texture.MM_LINEAR,
				Texture.FM_LINEAR );
		Texture south = TextureManager.loadTexture(
				Environment.class.getClassLoader().getResource(
						dir + "3.jpg" ),
				Texture.MM_LINEAR,
				Texture.FM_LINEAR );
		Texture east = TextureManager.loadTexture(
				Environment.class.getClassLoader().getResource(
						dir + "2.jpg" ),
				Texture.MM_LINEAR,
				Texture.FM_LINEAR );
		Texture west = TextureManager.loadTexture(
				Environment.class.getClassLoader().getResource(
						dir + "4.jpg" ),
				Texture.MM_LINEAR,
				Texture.FM_LINEAR );
		Texture up = TextureManager.loadTexture(
				Environment.class.getClassLoader().getResource(
						dir + "6.jpg" ),
				Texture.MM_LINEAR,
				Texture.FM_LINEAR );
		Texture down = TextureManager.loadTexture(
				Environment.class.getClassLoader().getResource(
						dir + "5.jpg" ),
				Texture.MM_LINEAR,
				Texture.FM_LINEAR );

		skybox.setTexture( Skybox.NORTH, north );
		skybox.setTexture( Skybox.WEST, west );
		skybox.setTexture( Skybox.SOUTH, south );
		skybox.setTexture( Skybox.EAST, east );
		skybox.setTexture( Skybox.UP, up );
		skybox.setTexture( Skybox.DOWN, down );

		CullState cullState = display.getRenderer().createCullState();
		cullState.setCullMode( CullState.CS_NONE );
		cullState.setEnabled( true );
		skybox.setRenderState( cullState );

		ZBufferState zState = display.getRenderer().createZBufferState();
		zState.setEnabled( false );
		skybox.setRenderState( zState );

		FogState fs = display.getRenderer().createFogState();
		fs.setEnabled( false );
		skybox.setRenderState( fs );

		skybox.setLightCombineMode( LightState.OFF );
		skybox.setCullMode( SceneElement.CULL_NEVER );
		skybox.setTextureCombineMode( TextureState.REPLACE );
		skybox.updateRenderState();

		skybox.lockBounds();
		
	}
	
	public Skybox getSkyBox(){
		return skybox;
	}
	
	
	public void update(float tpf){
		skybox.setLocalTranslation(DisplaySystem.getDisplaySystem().getRenderer().getCamera().getLocation());
		ev.getLocalTranslation().addLocal(Vector3f.UNIT_Z.mult(tpf * currentSpeed));
		ListIterator child = ev.getChildren().listIterator();
		while(child.hasNext()){
			Spatial test = (Spatial) child.next();
			if(test instanceof Terrain){
				Terrain t = (Terrain)test;
				t.update();
			}
		}
		ListIterator liste = enemys.listIterator();
		while(liste.hasNext()){
			Enemy next = (Enemy) liste.next();
			if(!next.isActive()){
				float distance = (player.getPlayer().getWorldTranslation().getY()-next.getEnemy().getWorldTranslation().getZ());
				if(distance<=300){
					System.out.println(next.getEnemy());
					next.activate();
				}
			}
		}
		
		
		if(checkSimpleCollision(player.getPlayer())){
			player.collision();
		}
	}
	
	public void cleanup(){
		lvlLoader.close();
	}

	public void addEnemy(Enemy enemy){
		enemys.add(enemy);
	}
	
	

	public Object call() throws Exception {
		skybox.preloadTextures();
		skybox.lockMeshes();
		return null;
	}
	public Player getPlayer() {
		return player;
	}
	public void setPlayer(Player player) {
		this.player=player;
	}
	public Texture getDetailTexture() {
		return texDetail;
	}
	
}
